package com.lqfan.autoAnswerQ.controller.importQuestions;
 
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.lqfan.autoAnswerQ.model.errorRecords.ImportErrorRecords;
import com.lqfan.autoAnswerQ.model.fileType.FileType;
import com.lqfan.autoAnswerQ.model.quesBank.Question;
import com.lqfan.autoAnswerQ.model.quesBank.QuesBankModel;
import com.lqfan.autoAnswerQ.model.subject.HandleImportModel;
import com.lqfan.autoAnswerQ.model.subject.Subject;
import com.lqfan.autoAnswerQ.model.subjectChoiceType.SubjectChoiceType;
import com.lqfan.autoAnswerQ.service.errorRecords.IImportErrorRecordsService;
import com.lqfan.autoAnswerQ.service.fileType.impl.FileTypeServiceImpl;
import com.lqfan.autoAnswerQ.service.quesBank.IQuestionService;
import com.lqfan.autoAnswerQ.service.subject.ISubjectService;

import com.lqfan.autoAnswerQ.utils.ResponseMessage;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


/**
 * 解析并保存题库
 *
 * @author lqfan
 */
@RestController
@RequestMapping(value = "/hello",produces = MediaType.APPLICATION_JSON_VALUE)
@Api(value = "导入题库接口")
public class PoiWordController {
    private static final String filePath = System.getProperty("user.dir");
    private static final Logger logger = LoggerFactory.getLogger(PoiWordController.class);

    @Autowired
    private ISubjectService subjectService;
    @Autowired
    private IQuestionService questionService;
    @Autowired
    private IImportErrorRecordsService errorRecordsService;

    @RequestMapping(value = "/word",method = RequestMethod.GET)
    public String helloWord(@RequestParam(value = "name") String string){
        logger.error("logback成功了吗");
        logger.debug("logback成功了吗");
        logger.info("logback 成功了");
        return string;
    }


    @ApiOperation(value="解析word文档", notes="按段落解析word文档")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "qFile", value = "题目文件", required = true, dataType = "__file"),
            @ApiImplicitParam(name = "aFile", value = "答案文件", required = true, dataType = "__file"),
            @ApiImplicitParam(name = "fileType", value = "题库类型(1 or 2 or 3 or 4)", required = true, dataType = "int"),
            @ApiImplicitParam(name = "userId", value = "用户id", required = true, dataType = "String"),
            @ApiImplicitParam(name = "fileName", value = "题库名", required = true, dataType = "String"),
            @ApiImplicitParam(name = "filePath", value = "路径('/测验/化学1/')", required = true, dataType = "String")
    })
    @RequestMapping(value = "importQues", method = RequestMethod.POST)
    @Transactional(isolation= Isolation.DEFAULT,propagation= Propagation.REQUIRED,rollbackFor = Exception.class)
    public ResponseMessage uploadFile(@RequestParam(value = "qFile") MultipartFile questionFile,
                                      @RequestParam(value = "aFile") MultipartFile answerFile,
                                      @RequestParam(value = "userId") String userId,
                                      @RequestParam(value = "fileType") int fileType,
                                      @RequestParam(value = "fileName") String fileName,
                                      @RequestParam(value = "filePath") String path){
        logger.info("开始上传题库文件");
        //获取文件名
//        String qName = questionFile.getOriginalFilename();

        String src = path+fileName+"/";
        //1.保存题库
        boolean saveRes = questionService.saveQuesBank(questionFile, answerFile, path, src, fileName, fileType, userId);
        if(!saveRes){
            //保存失败导入失败数据
            ImportErrorRecords errorInfo = new ImportErrorRecords();
            errorInfo.setErrorContent("保存题库信息失败");
            errorInfo.setUserId(userId);
            errorRecordsService.saveErrInfo(errorInfo);
            return ResponseMessage.fail("保存题库信息失败");
        }

        //2.解析文件
        boolean res = parseFile(questionFile, answerFile, src, userId);
        if(!res){
            ImportErrorRecords errorInfo = new ImportErrorRecords();
            errorInfo.setErrorContent("保存题库信息失败");
            errorInfo.setUserId(userId);
            errorRecordsService.saveErrInfo(errorInfo);
            return ResponseMessage.fail("保存题库信息失败！");
        }
        return ResponseMessage.success("保存题库信息成功！");
    }

    public boolean parseFile(MultipartFile questionFile, MultipartFile answerFile, String filePath, String userId) {
        ArrayList<Subject> subList = new ArrayList<>();
        ArrayList<SubjectChoiceType> choiceTypeList = new ArrayList<>();
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("filePath",filePath);
        queryWrapper.eq("userId", userId);
        Question oneQues = questionService.getOne(queryWrapper);
        String queBankId = oneQues.getId();
        //属于什么题型
        Integer subjectType = 0;
        String subId = null;
        boolean startTag = false;
        try {
            //解析题目文件
            XWPFDocument xwpfDocument = new XWPFDocument(questionFile.getInputStream());
            XWPFParagraph para;
            Iterator<XWPFParagraph> iterator = xwpfDocument.getParagraphsIterator();
            while (iterator.hasNext()) {
                para = iterator.next();
                logger.info("输出：{}", para.getText());
                String words = para.getText();
                switch (words) {
                    case "|单选|":
                        subjectType = 1;
                        startTag = true;
                        break;
                    case "|多选|":
                        subjectType = 2;
                        break;
                    case "|判断|":
                        subjectType = 3;
                        break;
                    case "|填空|":
                        subjectType = 4;
                        break;
                    default:
                        if(!startTag || words.isEmpty()) {
                            break;
                        }
                        String[] str = words.split("\\.");
                        Pattern pattern = Pattern.compile("-?[0-9]+\\.?[0-9]*");
                        Matcher isNum = pattern.matcher(str[0]);
                        if ((!isNum.matches() && !words.endsWith(")") && !words.endsWith("）"))) {
                            //是选项,存入选项对象
                            String id = String.valueOf(UUID.randomUUID());
                            SubjectChoiceType choiceType = packSubjectChoiceType(id, subId, str[0], str[1]);
                            choiceTypeList.add(choiceType);
                        } else if(words.endsWith(")") || words.endsWith("）") || words.contains("____")){
                            //存入题目对象
                            String id = String.valueOf(UUID.randomUUID());
                            Subject subject = packSubject(id, queBankId, subjectType, str[1],userId);
                            subId = id;
                            if (subjectType==4) {
                                //填空题选项为空
                                choiceTypeList.add(packSubjectChoiceType(String.valueOf(UUID.randomUUID()), subId, null, null));
                            }
                            subList.add(subject);
                        } else if(isNum.matches()){

                        }
                }
            }
            //解析答案文件
            XWPFDocument answerDocument = null;
            answerDocument = new XWPFDocument(answerFile.getInputStream());
            XWPFParagraph answerPara;
            Iterator<XWPFParagraph> answerIterator = answerDocument.getParagraphsIterator();
            int i=0;
            while (answerIterator.hasNext()) {
                answerPara = answerIterator.next();
                logger.info("输出：{}", answerPara.getText());
                String words = answerPara.getText();
                String[] strArr = words.split("\\.");
                for (int j = 0; j <strArr.length ; j++) {
                    logger.info("输出修改后的：{}", strArr[j]);
                }

                subList.get(i).setAnswer(strArr[1]);
                i++;
            }
            //批量增加
            boolean res = subjectService.saveHandle(subList, choiceTypeList);
            if (!res){
                ImportErrorRecords errorInfo = new ImportErrorRecords();
                errorInfo.setErrorContent("题目增加失败");
                errorInfo.setUserId(userId);
                errorRecordsService.saveErrInfo(errorInfo);
            }
            return res;
        } catch (IOException e) {
            ImportErrorRecords errorInfo = new ImportErrorRecords();
            errorInfo.setErrorContent("题目不符合格式要求");
            errorInfo.setUserId(userId);
            errorRecordsService.saveErrInfo(errorInfo);
            e.printStackTrace();
            return false;
        }
    }

    //到时具体修改一下 新建文件
    @ApiOperation(value="手动输入题目", notes="手动输入题目")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "quesBankModel", value = "题目对象", required = true, dataType = "json"),
            @ApiImplicitParam(name = "fileType", value = "路径类型", required = true, dataType = "int"),
    })
    @RequestMapping(value = "handleImportQues", method = RequestMethod.POST,produces = "application/json;charset=UTF-8")
    public ResponseMessage handleImportQues(@RequestBody QuesBankModel quesBankModel,@RequestBody int qFileType) {
        logger.info(String.valueOf(quesBankModel));
        String userId = quesBankModel.getUserId();
        String path = quesBankModel.getFilePath();
        int questionFileType = quesBankModel.getQuestionFileType();  //题库类型   word、ppt
        String fileName = quesBankModel.getFileName();
        String quesBankId = String.valueOf(UUID.randomUUID());
        String src = filePath + "/source/" +qFileType+"/"+ userId+path;

        //文件路径对象
        FileType fileType = new FileType();
        fileType.setUserId(userId);
        fileType.setPid(path);
        fileType.setType(qFileType);
        fileType.setFilePath(src);

        //题库对象
        Question quesBank = new Question();
        quesBank.setUserId(userId);
        quesBank.setQuestionFileType(questionFileType);
        quesBank.setQuestionName(fileName);
        quesBank.setFilePath(src);
        quesBank.setId(quesBankId);
        //题目对象
        ArrayList<HandleImportModel> subjectList = quesBankModel.getHandleImportModels();
        subjectList.forEach(subject -> {
            subject.setQuestionId(quesBankId);
            subject.setId(String.valueOf(UUID.randomUUID()));
            subject.setUserId(userId);
        });
        //批量增加
        boolean res = subjectService.saveHandle(subjectList, quesBank, fileType);
        if (!res){
            ImportErrorRecords errorInfo = new ImportErrorRecords();
            errorInfo.setErrorContent("手动导入失败！");
            errorInfo.setUserId(userId);
            errorRecordsService.saveErrInfo(errorInfo);
            return ResponseMessage.fail("手动导入失败！");
        }
        return ResponseMessage.success("手动导入成功！");
    }

    @ApiOperation(value="手动输入题目", notes="手动输入题目")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "quesBankModel", value = "题目对象", required = true, dataType = "json"),
            @ApiImplicitParam(name = "fileType", value = "路径类型", required = true, dataType = "int"),
    })
    @RequestMapping(value = "handleImportSubject", method = RequestMethod.POST,produces = "application/json;charset=UTF-8")
    public ResponseMessage handleImportSubject(@RequestBody QuesBankModel quesBankModel,@RequestBody int qFileType) {
        logger.info(String.valueOf(quesBankModel));
        String userId = quesBankModel.getUserId();
        String path = quesBankModel.getFilePath();
        int questionFileType = quesBankModel.getQuestionFileType();  //题库类型   word、ppt
        String fileName = quesBankModel.getFileName();
        String quesBankId = String.valueOf(UUID.randomUUID());
        String src = filePath + "/source/" +qFileType+"/"+ userId+path;

        //文件路径对象
        FileType fileType = new FileType();
        fileType.setUserId(userId);
        fileType.setPid(path);
        fileType.setType(qFileType);
        fileType.setFilePath(src);

        //题库对象
        Question quesBank = new Question();
        quesBank.setUserId(userId);
        quesBank.setQuestionFileType(questionFileType);
        quesBank.setQuestionName(fileName);
        quesBank.setFilePath(src);
        quesBank.setId(quesBankId);
        //题目对象
        ArrayList<HandleImportModel> subjectList = quesBankModel.getHandleImportModels();
        subjectList.forEach(subject -> {
            subject.setQuestionId(quesBankId);
            subject.setId(String.valueOf(UUID.randomUUID()));
            subject.setUserId(userId);
        });
        //批量增加
        boolean res = subjectService.saveHandle(subjectList, quesBank, fileType);
        if (!res){
            ImportErrorRecords errorInfo = new ImportErrorRecords();
            errorInfo.setErrorContent("手动导入失败！");
            errorInfo.setUserId(userId);
            errorRecordsService.saveErrInfo(errorInfo);
            return ResponseMessage.fail("手动导入失败！");
        }
        return ResponseMessage.success("手动导入成功！");
    }

    /**
     * 封装Subject对象
     * @return
     */
    private Subject packSubject(String id, String queBankId, int type, String content,String userId){
        Subject subject = new Subject();
        subject.setId(id);
        subject.setQuestionId(queBankId);
        subject.setTypeId(type);
        subject.setContent(content);
        subject.setUserId(userId);
        return subject;
    }

    /**
     * 封装SubjectChoiceType对象
     * @return
     */
    private SubjectChoiceType packSubjectChoiceType(String id, String subId, String choiceNumber, String content){
        SubjectChoiceType choiceType = new SubjectChoiceType();
        choiceType.setId(id);
        choiceType.setContent(content);
        choiceType.setChoiceNumber(choiceNumber);
        choiceType.setSubjectId(subId);
        return choiceType;
    }
}